package org.example.config;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.state.ConnectionState;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.example.ZookeeperProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.concurrent.CountDownLatch;

/**
 * @author shenguangyang
 */
@Configuration
public class MyCuratorConfig {
    private static final Logger log = LoggerFactory.getLogger(MyCuratorConfig.class);
    @Resource
    private ZookeeperProperties zookeeperProperties;

    @PostConstruct
    public void init() {
        System.out.println("CuratorConfig init");
    }

    /**
     * commons-lock-spring-boot-starter 依赖中会自动配置的, 所以如果要使用
     * 该依赖封装好的Curator则不需要添加@Bean, 你也可以添加@Bean, 则该依赖中关于
     * Curator的配置就不会生效的
     * @return
     */
//    @Bean
    public CuratorFramework curatorFramework() {
        // 重试策略, 初试时间 3 秒，重试 3 次
        RetryPolicy policy = new ExponentialBackoffRetry(5000, 3);
        // 通过工厂创建 Curator
        String connectString = zookeeperProperties.getAddress();
        int connectionTimeout = zookeeperProperties.getSessionTimeout();
        int sessionTimeout = zookeeperProperties.getSessionTimeout();
        CuratorFramework curatorFramework = CuratorFrameworkFactory.builder()
                        .connectString(connectString)
                        .connectionTimeoutMs(connectionTimeout)
                        .sessionTimeoutMs(sessionTimeout)
                        .retryPolicy(policy).build();
        CountDownLatch waitConnectionLatch = new CountDownLatch(1);
        curatorFramework.getConnectionStateListenable().addListener((client, newState) -> {
            if (newState == ConnectionState.CONNECTED) {
                log.info("curator connection zookeeper success！");
                waitConnectionLatch.countDown();
            }
        });
        log.info("curator connection zookeeper......");
        // 开启连接
        curatorFramework.start();
        try {
            waitConnectionLatch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return curatorFramework;
    }
}
